__author__ = 'Daan'

import unittest
import xmlrpclib
import os
import shutil

from unittests.stubs import ServerProxy, stub_os

from pPhotoClient import PhotoClient

TEST_DIR = os.path.join( os.path.dirname( __file__ ), "dat" )
UNITTEST_OUTPUT_DIR = os.path.join( TEST_DIR, "output" )

class PhotoClientTester( unittest.TestCase ):

    verbose = True

    def setUp( self ):
        """
        DOCSTRING
        """
        if not os.path.isdir( UNITTEST_OUTPUT_DIR ):
            os.makedirs( UNITTEST_OUTPUT_DIR )

    def tearDown( self ):
        """
        DOCSTRING
        """
        shutil.rmtree( UNITTEST_OUTPUT_DIR, True )

    def test_01_instantiation( self ):
        """
        """

        testObject = PhotoClient.PhotoClient( 0.1, 1, 2, TEST_DIR )

        self.assertIsInstance( testObject, PhotoClient.PhotoClient )

    def test_02_checkForFileUpdates( self ):
        with stub_os.stub_os( verbose = self.verbose ) as os_stub:
            os_stub.stub_listdir( [] )

            testObject = PhotoClient.PhotoClient( 1, 2, 3, TEST_DIR, extensions = ["jpg", "jpeg", "png"] )

            #===========================================================================================================
            testObject.filescanIntervalCountdown = testObject.filescanInterval
            testObject.checkForFileUpdates()

            self.assertIsInstance( testObject.filesToSend, list )
            self.assertEqual( len( testObject.filesToSend ), 0 )

            #===========================================================================================================
            os_stub.stub_listdir( ["a.jpeg", "b.jpg", "bloep.txt"] )

            testObject.filescanIntervalCountdown = testObject.filescanInterval
            testObject.checkForFileUpdates()

            self.assertIsInstance( testObject.filesToSend, list )
            self.assertEqual( len( testObject.filesToSend ), 2 )

            #===========================================================================================================
            os_stub.stub_listdir( ["a", "b"] )

            testObject.filescanIntervalCountdown = testObject.filescanInterval
            testObject.checkForFileUpdates()

            self.assertIsInstance( testObject.filesToSend, list )
            self.assertEqual( len( testObject.filesToSend ), 0 )

            #===========================================================================================================
            os_stub.stub_listdir()

            testObject.filescanIntervalCountdown = testObject.filescanInterval
            testObject.checkForFileUpdates()

            self.assertIsInstance( testObject.filesToSend, list )
            self.assertEqual( len( testObject.filesToSend ), 0 )


    def test_03_checkForFileUpdates_Error_init( self ):
        with stub_os.stub_os( verbose = self.verbose ) as os_stub:
            os_stub.stub_listdir_raise( retval = [], raiseOnMatch = [TEST_DIR], exc_type = IOError, exc_msg = "File IO Error" )

            testObject = PhotoClient.PhotoClient( 1, 2, 3, TEST_DIR, extensions = ["jpg", "jpeg", "png"] )

            self.assertIsInstance( testObject, PhotoClient.PhotoClient )
            self.assertEqual( testObject.filescanStoredDict, {} )
            self.assertEqual( len( testObject.filescanStoredDict ), 0 )

            os_stub.stub_listdir_raise( retval = [], raiseOnMatch = [TEST_DIR], exc_type = Exception, exc_msg = "General Exception" )

            self.assertRaises( Exception, PhotoClient.PhotoClient, 1, 2, 3, TEST_DIR, extensions = ["jpg", "jpeg", "png"] )

    def test_04_checkForFileUpdates_Error_function( self ):
        with stub_os.stub_os( verbose = self.verbose ) as os_stub:
            os_stub.stub_listdir( [] )

            testObject = PhotoClient.PhotoClient( 1, 2, 3, TEST_DIR, extensions = ["jpg", "jpeg", "png"] )

            os_stub.stub_listdir_raise( retval = [], raiseOnMatch = [TEST_DIR], exc_type = IOError, exc_msg = "File IO Error" )
            #===========================================================================================================
            testObject.checkForFileUpdates()
            testObject.checkForFileUpdates()

            self.assertIsInstance( testObject.filesToSend, list )
            self.assertEqual( len( testObject.filesToSend ), 0 )

            os_stub.stub_listdir_raise( retval = [], raiseOnMatch = [TEST_DIR], exc_type = Exception, exc_msg = "General Exception" )

            testObject.filescanIntervalCountdown = testObject.filescanInterval
            self.assertRaises( Exception, testObject.checkForFileUpdates )

    def test_05_updateMachineList( self ):
        with ServerProxy.ServerProxy_stub( verbose = self.verbose ) as proxy, stub_os.stub_os( verbose = self.verbose ) as os_stub:
            os_stub.stub_listdir( [] )
            proxy.stub( machineListReturn = ["unittest.local"] )

            testObject = PhotoClient.PhotoClient( 1, 2, 4, TEST_DIR, name = "unittesting", extensions = ["jpg"] )

            testObject.proxy = xmlrpclib.ServerProxy( "unittest.local" )

            testObject.updateMachineList()
            self.assertEqual( testObject.updateMachineListCountdown, 1 )

            testObject.updateMachineList()

            self.assertTrue( ["unittesting", 9001] in proxy.registerMachineList )
            self.assertEqual( testObject.machineList, ["unittest.local"] )
            self.assertEqual( testObject.updateMachineListCountdown, 0 )

    def test_06_updateMachineList_Error( self ):

        import socket

        with ServerProxy.ServerProxy_stub( verbose = self.verbose ) as proxy, stub_os.stub_os( verbose = self.verbose ) as os_stub:
            os_stub.stub_listdir( [] )
            proxy.stub_error( exc_type = socket.error, exc_msg = "Socket Error" )

            testObject = PhotoClient.PhotoClient( 1, 2, 4, TEST_DIR, name = "unittesting", extensions = ["jpg"] )

            testObject.proxy = xmlrpclib.ServerProxy( "unittest.local" )

            testObject.updateMachineList()
            self.assertEqual( testObject.updateMachineListCountdown, 1 )

            testObject.updateMachineList()

            self.assertEqual( testObject.machineList, [] )

    def test_07_sendFiles( self ):
        with ServerProxy.ServerProxy_stub( verbose = self.verbose ) as proxy, stub_os.stub_os( verbose = self.verbose ) as os_stub:
            os_stub.stub_listdir( [] )
            os_stub.stub_open()
            proxy.stub( machineListReturn = ["unittest.local"] )

            testObject = PhotoClient.PhotoClient( 1, 2, 4, TEST_DIR, name = "unittesting", extensions = ["jpg"] )

            testObject.proxy = xmlrpclib.ServerProxy( "unittest.local" )

            testObject.filesToSend = ["a.jpg", "b.jpg"]

            testObject.sendFiles()

    def test_08_sendFiles_Error_read( self ):
        pass

    def test_09_sendFiles_Error_send( self ):
        pass
